prepare($sql);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("Get classes error: " . $e->getMessage());
return [];
}
}
function getAcademicYears() {
global $DBcon;
try {
$sql = "SELECT academic_year FROM calender ORDER BY academic_year DESC";
$stmt = $DBcon->prepare($sql);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("Get academic years error: " . $e->getMessage());
return [];
}
}
// NEW FUNCTION: Insert record into promoted table
function insertIntoPromotedTable($regno, $academic_year, $class_id) {
global $DBcon;
try {
$sql = "INSERT INTO promoted (regno, accademic_year, class_id)
VALUES (:regno, :accademic_year, :class_id)";
$stmt = $DBcon->prepare($sql);
$result = $stmt->execute([
':regno' => sanitize_input($regno),
':accademic_year' => sanitize_input($academic_year),
':class_id' => sanitize_input($class_id)
]);
return $result;
} catch (PDOException $e) {
error_log("Insert into promoted table error: " . $e->getMessage());
return false;
}
}
// NEW FUNCTION: Update record in promoted table
function updatePromotedTable($old_regno, $new_regno, $academic_year, $class_id) {
global $DBcon;
try {
// First check if record exists in promoted table
$check_sql = "SELECT sn FROM promoted WHERE regno = :old_regno";
$check_stmt = $DBcon->prepare($check_sql);
$check_stmt->execute([':old_regno' => sanitize_input($old_regno)]);
$existing_record = $check_stmt->fetch(PDO::FETCH_ASSOC);
if ($existing_record) {
// Update existing record
$sql = "UPDATE promoted
SET regno = :new_regno,
accademic_year = :accademic_year,
class_id = :class_id
WHERE regno = :old_regno";
$stmt = $DBcon->prepare($sql);
$result = $stmt->execute([
':new_regno' => sanitize_input($new_regno),
':accademic_year' => sanitize_input($academic_year),
':class_id' => sanitize_input($class_id),
':old_regno' => sanitize_input($old_regno)
]);
} else {
// Insert new record if not exists
$result = insertIntoPromotedTable($new_regno, $academic_year, $class_id);
}
return $result;
} catch (PDOException $e) {
error_log("Update promoted table error: " . $e->getMessage());
return false;
}
}
// NEW FUNCTION: Delete record from promoted table
function deleteFromPromotedTable($regno) {
global $DBcon;
try {
$sql = "DELETE FROM promoted WHERE regno = :regno";
$stmt = $DBcon->prepare($sql);
return $stmt->execute([':regno' => sanitize_input($regno)]);
} catch (PDOException $e) {
error_log("Delete from promoted table error: " . $e->getMessage());
return false;
}
}
// CRUD Functions
function getAllStudents($filters = [], $page = 1, $per_page = 25) {
global $DBcon;
try {
// Build WHERE clause based on filters
$where_clause = "";
$params = [];
if (!empty($filters['class_id'])) {
$where_clause .= " WHERE class_id = :class_id";
$params[':class_id'] = $filters['class_id'];
}
if (!empty($filters['admin_year'])) {
$where_clause .= empty($where_clause) ? " WHERE" : " AND";
$where_clause .= " admin_year = :admin_year";
$params[':admin_year'] = $filters['admin_year'];
}
// Get total count for pagination
$count_sql = "SELECT COUNT(*) as total FROM students_info" . $where_clause;
$count_stmt = $DBcon->prepare($count_sql);
$count_stmt->execute($params);
$total_result = $count_stmt->fetch(PDO::FETCH_ASSOC);
$total_records = $total_result['total'];
$total_pages = ceil($total_records / $per_page);
// Calculate offset
$offset = ($page - 1) * $per_page;
// Get students with pagination
$sql = "SELECT * FROM students_info" . $where_clause . " ORDER BY sn DESC LIMIT :offset, :per_page";
$stmt = $DBcon->prepare($sql);
// Bind parameters
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':per_page', $per_page, PDO::PARAM_INT);
$stmt->execute();
$students = $stmt->fetchAll(PDO::FETCH_ASSOC);
return [
'students' => $students,
'total_records' => $total_records,
'total_pages' => $total_pages,
'current_page' => $page
];
} catch (PDOException $e) {
error_log("Get all students error: " . $e->getMessage());
return [
'students' => [],
'total_records' => 0,
'total_pages' => 0,
'current_page' => 1
];
}
}
function getStudent($id) {
global $DBcon;
try {
$sql = "SELECT * FROM students_info WHERE sn = :id";
$stmt = $DBcon->prepare($sql);
$stmt->execute([':id' => intval($id)]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result;
} catch (PDOException $e) {
error_log("Get student error: " . $e->getMessage());
return false;
}
}
function createStudent($data, $files) {
global $DBcon;
try {
$image_path = handleImageUpload($files, $data);
$sql = "INSERT INTO students_info (fullname, regno, class_id, admin_year, image)
VALUES (:fullname, :regno, :class_id, :admin_year, :image)";
$stmt = $DBcon->prepare($sql);
$result = $stmt->execute([
':fullname' => sanitize_input($data['fullname']),
':regno' => sanitize_input($data['regno']),
':class_id' => sanitize_input($data['class_id']),
':admin_year' => sanitize_input($data['admin_year']),
':image' => $image_path
]);
// INSERT INTO PROMOTED TABLE - NEW CODE ADDED
if ($result) {
$promoted_result = insertIntoPromotedTable($data['regno'], $data['admin_year'], $data['class_id']);
if (!$promoted_result) {
error_log("Failed to insert into promoted table for student: " . $data['regno']);
// Don't return false here as student creation was successful
// Just log the error for the promoted table insertion
}
}
return $result;
} catch (PDOException $e) {
error_log("Create student error: " . $e->getMessage());
return false;
}
}
function updateStudent($data, $files) {
global $DBcon;
try {
// Get current student data first
$current_student = getStudent($data['id']);
if (!$current_student) {
return false;
}
// Handle image upload
$image_path = handleImageUpload($files, $data);
// If no new image was uploaded, keep the current image
if ($image_path === '') {
$image_path = $current_student['image'];
} else if ($image_path !== false) {
// New image was uploaded successfully, delete old image if it exists
if (!empty($current_student['image']) && file_exists('../' . $current_student['image'])) {
unlink('../' . $current_student['image']);
}
} else {
// Image upload failed
$image_path = $current_student['image'];
}
$sql = "UPDATE students_info
SET fullname = :fullname,
regno = :regno,
class_id = :class_id,
admin_year = :admin_year,
image = :image
WHERE sn = :id";
$stmt = $DBcon->prepare($sql);
$params = [
':fullname' => sanitize_input($data['fullname']),
':regno' => sanitize_input($data['regno']),
':class_id' => sanitize_input($data['class_id']),
':admin_year' => sanitize_input($data['admin_year']),
':image' => $image_path,
':id' => intval($data['id'])
];
$result = $stmt->execute($params);
// UPDATE PROMOTED TABLE - NEW CODE ADDED
if ($result) {
$update_promoted = updatePromotedTable($current_student['regno'], $data['regno'], $data['admin_year'], $data['class_id']);
if (!$update_promoted) {
error_log("Failed to update promoted table for student: " . $data['regno']);
// Don't return false here as student update was successful
// Just log the error for the promoted table update
}
}
return $result;
} catch (PDOException $e) {
error_log("Update student error: " . $e->getMessage());
return false;
}
}
function handleImageUpload($files, $data) {
// Check for webcam image first
if (!empty($data['webcam_image']) && $data['webcam_image'] !== 'data:,') {
return saveWebcamImage($data['webcam_image']);
}
// Check for file upload
if (isset($files['image_upload']) && $files['image_upload']['error'] === UPLOAD_ERR_OK) {
return saveUploadedImage($files['image_upload']);
}
// No image provided - return empty string
return '';
}
function saveWebcamImage($base64_image) {
$upload_dir = '../uploads/students/';
// Create upload directory if it doesn't exist
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Extract base64 data
if (preg_match('/^data:image\/(\w+);base64,/', $base64_image, $type)) {
$image_data = substr($base64_image, strpos($base64_image, ',') + 1);
$type = strtolower($type[1]); // jpg, png, gif
if (!in_array($type, ['jpg', 'jpeg', 'png', 'gif'])) {
return false;
}
$image_data = base64_decode($image_data);
if ($image_data === false) {
return false;
}
} else {
return false;
}
$filename = 'student_' . uniqid() . '.' . $type;
$filepath = $upload_dir . $filename;
if (file_put_contents($filepath, $image_data)) {
return 'uploads/students/' . $filename;
}
return false;
}
function saveUploadedImage($file) {
$upload_dir = '../uploads/students/';
$allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
$max_size = 2 * 1024 * 1024; // 2MB
// Create upload directory if it doesn't exist
if (!file_exists($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Validate file
if (!in_array($file['type'], $allowed_types)) {
return false;
}
if ($file['size'] > $max_size) {
return false;
}
// Generate unique filename
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$filename = 'student_' . uniqid() . '.' . $extension;
$filepath = $upload_dir . $filename;
if (move_uploaded_file($file['tmp_name'], $filepath)) {
return 'uploads/students/' . $filename;
}
return false;
}
function deleteStudent($id) {
global $DBcon;
try {
// Get student data first to delete from promoted table
$student = getStudent($id);
if (!$student) {
return false;
}
// DELETE FROM PROMOTED TABLE - NEW CODE ADDED
if ($student && !empty($student['regno'])) {
$delete_promoted = deleteFromPromotedTable($student['regno']);
if (!$delete_promoted) {
error_log("Failed to delete from promoted table for student: " . $student['regno']);
// Continue with student deletion even if promoted table deletion fails
}
}
// Delete student image if it exists
if (!empty($student['image']) && file_exists('../' . $student['image'])) {
unlink('../' . $student['image']);
}
$sql = "DELETE FROM students_info WHERE sn = :id";
$stmt = $DBcon->prepare($sql);
return $stmt->execute([':id' => intval($id)]);
} catch (PDOException $e) {
error_log("Delete student error: " . $e->getMessage());
return false;
}
}
// Generate CSRF token
$csrf_token = generate_csrf_token();
// Get classes and academic years
$classes = getClasses();
$academic_years = getAcademicYears();
// Initialize variables
$action = isset($_GET['action']) ? sanitize_input($_GET['action']) : 'list';
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$message = '';
$message_type = '';
$student = null;
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Validate CSRF token
if (!validate_csrf_token($_POST['csrf_token'])) {
$message = 'Security token validation failed.';
$message_type = 'error';
} else {
// Process different actions
switch ($_POST['action']) {
case 'create':
$result = createStudent($_POST, $_FILES);
if ($result) {
$message = 'Student created successfully.';
$message_type = 'success';
$action = 'list';
} else {
$message = 'Failed to create student. Please try again.';
$message_type = 'error';
}
break;
case 'update':
$result = updateStudent($_POST, $_FILES);
if ($result) {
$message = 'Student updated successfully.';
$message_type = 'success';
$action = 'list';
} else {
$message = 'Failed to update student. Please try again.';
$message_type = 'error';
}
break;
case 'delete':
$result = deleteStudent($_POST['id']);
if ($result) {
$message = 'Student deleted successfully.';
$message_type = 'success';
} else {
$message = 'Failed to delete student. Please try again.';
$message_type = 'error';
}
break;
case 'bulk_delete':
if (isset($_POST['selected_students']) && is_array($_POST['selected_students'])) {
$success_count = 0;
$error_count = 0;
foreach ($_POST['selected_students'] as $student_id) {
if (deleteStudent($student_id)) {
$success_count++;
} else {
$error_count++;
}
}
if ($success_count > 0) {
$message = "Successfully deleted $success_count student(s).";
$message_type = 'success';
if ($error_count > 0) {
$message .= " Failed to delete $error_count student(s).";
}
} else {
$message = 'Failed to delete selected students.';
$message_type = 'error';
}
} else {
$message = 'No students selected for deletion.';
$message_type = 'error';
}
break;
}
}
}
// If editing, get student data
if ($action === 'edit') {
$student = getStudent($id);
if (!$student) {
$message = 'Student not found.';
$message_type = 'error';
$action = 'list';
}
}
// Get filter parameters
$filter_class = isset($_GET['filter_class']) ? sanitize_input($_GET['filter_class']) : '';
$filter_year = isset($_GET['filter_year']) ? sanitize_input($_GET['filter_year']) : '';
$current_page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
// Build filters array
$filters = [];
if (!empty($filter_class)) {
$filters['class_id'] = $filter_class;
}
if (!empty($filter_year)) {
$filters['admin_year'] = $filter_year;
}
// Get students with filters and pagination
$students_data = getAllStudents($filters, $current_page, 25);
$students = $students_data['students'];
$total_records = $students_data['total_records'];
$total_pages = $students_data['total_pages'];
?>
Student Management - School Admin